/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * This file is part of retabel.
 *
 * Copyright (c) 2011 by individual contributors as indicated by the
 * @author tags. See the copyright.txt file in the distribution
 * for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package samples.util;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.Test;
import org.retabel.RestServiceUtil;
import org.retabel.ZipArchiveBuilder;
import org.retabel.persistence.entity.report.RenderingEngineEnum;
import org.retabel.web.rest.RenderServiceBean;
import org.retabel.web.rest.RenderedDocumentServiceBean;
import org.retabel.web.rest.ReportDesignPackageServiceBean;
import xsd.rendereddocument.RenderedDocument;
import xsd.rendereddocument.RenderedDocumentPart;

import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Utility functions to assure correct document renderings
 * <p/>
 * <h3>Extra-Info</h3>
 * Created: 23:51 22.06.11
 *
 * @author Peter Herber
 * @version 1.0
 */
public class RenderUtils {


    /**
     * Tests if the rendered document with the given identifier exists and that there is exactly one pdf associated to it
     * @param uniqueRenderedDocumentIdentifier the rendered document unique identifier
     *
     * @throws InterruptedException if such exception occurs
     */
    public static void assertRenderedDocument(String uniqueRenderedDocumentIdentifier) throws InterruptedException {
        Client client = Client.create();

        Assert.assertNotNull(uniqueRenderedDocumentIdentifier);

        UriBuilder uriBuilder;WebResource webResource;ClientResponse response;
        uriBuilder = RestServiceUtil.getRestInterfaceUriBuilder().path(RenderedDocumentServiceBean.class).path(
            uniqueRenderedDocumentIdentifier);

        webResource = client.resource(uriBuilder.build());

        // now poll the rendered document by it's unique identifier
        RenderedDocument renderedDocument = null;
        for (int i=0; i<10; i++) {
            // wait a second, give the render engine the time to render the document
            Thread.sleep(1000);

            renderedDocument = webResource.get(RenderedDocument.class);
        }

        Assert.assertNotNull(renderedDocument);
        Assert.assertEquals(uniqueRenderedDocumentIdentifier, renderedDocument.getDocumentIdentifier());
        Assert.assertEquals(1, renderedDocument.getList().getRenderedDocumentPart().size());

        RenderedDocumentPart renderedDocumentPart = renderedDocument.getList().getRenderedDocumentPart().get(0);

        // download the rendered document and test if it's exists
        uriBuilder = RestServiceUtil.getRestInterfaceUriBuilder().path(RenderedDocumentServiceBean.class).path(
            uniqueRenderedDocumentIdentifier).path(Integer.toString(renderedDocumentPart.getId()));

        webResource = client.resource(uriBuilder.build());
        response = webResource.get(ClientResponse.class);

        Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
        Assert.assertEquals("application/pdf", response.getType().toString());
        Assert.assertTrue(response.getLength() > 0);
    }

    /**
     * Returns the resource within the class path lying relative to the given class as byte array
     * @param resource the resource within the class path
     * @param relativeToClass the resource relative to this class in class path, if null the current class loader is being used
     * @return the resource as byte array
     * @throws IOException if the resource was not found or if such exception occurs
     */
    public static byte[] getResourceAsByteArray(String resource, Class<?> relativeToClass) throws IOException {
        InputStream inputStream = null;

        if (relativeToClass == null) {
            inputStream = RenderUtils.class.getClassLoader().getResourceAsStream(resource);
        } else {
            inputStream = relativeToClass.getResourceAsStream(resource);
        }

        if (inputStream == null) {
            throw new IOException("resource not found: "+resource);
        }

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        IOUtils.copy(inputStream, byteArrayOutputStream);
        inputStream.close();

        return byteArrayOutputStream.toByteArray();
    }

}
